Skip to main content

Secure Development Guide

This is our practical SSDLC guide for everyday development. The goal is to make secure-by-default changes without having to read the full SSDLC for each ticket.

This is a distilled view of our SSDLC and the underlying TR-03187 requirements. It does not replace the full document; it focuses on what we need to do in our daily dev work. The full document lives here.

This document itself includes only information and prescriptions for the entire CIVITAS/CORE team.

This document is meant to be used in conjunction with the following team specific guidelines:

  • Security Architecture Principles: This document needs to be followed by everyone creating a ticket. It includes architecture-wide/overarching design principles that need to be incorporated into requirements and designs; they affect the coding phase only via the specifications from the ticket.
  • Backend-Style Guide: This document is intended for Team 1 and the backend developers of Team 2 (including Model Atlas)
  • Frontend-Style Guide: This document is intended for the Frontend developers of Team 2
  • DevOps Deployment Standards: This document contains prescriptions for Team 3.
  • Open Source Standards: This policy is to followed whenever new open source components are selected

1. Scope & Roles (developer view)

Developer responsibilities

You are responsible for:

  • writing secure code and avoiding unnecessary increases of attack surface,
  • keeping defaults safe,
  • shipping only the necessary artifacts (no debugging tools, no unused dependencies)
  • updating the SRN / threat model when you change boundaries (more on what that means in section 3),
  • ensuring the CI pipeline is green and security findings are addressed (we enforce this anyway), and
  • escalating high sensitivity changes for dedicated security review.

What you do not need to handle manually

CI and release tooling already:

  • run SAST and linters on each change,
  • run dependency and license scans and enforce policies,
  • perform secret scanning on commits and images,
  • generate SBOMs and attach them to releases, and
  • build and sign release artifacts.

You do not need to:

  • Run these tools locally (unless it speeds you up, e.g. by shortening the feedback cycle when you’re trying to fix it),
  • manually construct SBOMs or signatures, or
  • maintain separate spreadsheets / lists of dependencies.

You do need to:

  • keep the pipeline green, and
  • investigate and fix or explicitly document exceptions for any security findings.

Operators are responsible for hosting, monitoring, backups, incident response, and their local ISMS. We are responsible for enabling them through documentation and guidance.

2. Working with the MR checklists

When merging from your feature branch to the dev branch, you SHOULD fill in the non functional requirement checklist. As this may not be feasible in early stages of work on a feature, it is not mandatory. Before closing a ticket, you MUST refer to the MR (e.g. using the Closes functionality in Gitlab) and the checklist MUST be filled out. You MAY NOT close tickets based on MRs that do not either

  • Fulfill all non functional requirements OR
  • Mark them as non-applicable (with a short comment)

Comments for non-applicability should be commensurate to the complexity of the MR, e.g. if you only fix a typo in the front end, it is permissible to just comment "trivial change", whereas for a complex user facing feature, you would be expected to add a paragraph on why a certain NFR is not applicable.

3. Requirements you need to fulfill

Keep defaults secure

  • New feature flags default to the safest mode (least privilege, minimal exposure).
  • New configuration options have a documented “secure default” and reasoning.
  • If the feature employs Authentication or Authorization, default to a "block all" setting

Interfaces

For each externally reachable interface:

  • Enforce input validation and authentication at the first entry point.

Dependencies

  • Before adding a dependency, consider if it actually adds value considering the risk of adding a component. As a rule of thumb, anything that's less than 50 lines of code should not be added through a dependency, but instead added in code.
  • When adding a new dependency:
    • Ensure it is pinned in the lockfile
    • Add a short rationale to the MR (why did you choose this particular library over others? Why do you think this component is secure enough?): This policy is to followed whenever new open source components are selected).
    • For high risk/widely used components, note the risk as calculated from the scheme in the [Open Source Standards](../../Architecture/Architecture_General/Open_Source_Standards.md. For these components, the MR reviewer must also comment on the reasoning.
    • Make reasonable effort to minimize dependencies/shipped binaries

Dependency analysis and SBOM generation are handled in CI, but you are responsible for choosing appropriate dependencies. If you need help choosing, ping your team mates or the security team.

Miscellaneous

  • Encode/sanitize any content that is rendered into HTML or passed to shell/system calls.
  • Do not commit secrets, keys, or tokens to the repository (secret scanning should find out if you do :) ).
  • Pull all secrets from environment variables (which are then to be pulled from Kubernetes Secrets at runtime)
  • Should it be deemed beneficial to display debugging output in development environments (e.g. stack traces), add a mechanism to turn these on or off, with a default of "off".
  • Do not display information about versions or components to unauthenticated users. Do not display information about internal components to non-admin users.
  • Do not pass sensitive information in URLs. Always use the HTTP Body for that.

Testing

  • Unit/integration tests for authorization decisions (allowed vs blocked)
  • Tests for error paths
  • Tests for cross-tenant or cross-context access attempts where relevant.

Vulnerability Management

  • Before Dev can be merged to Main, all Vulnerabilities by the CI chain must be removed or triaged.
  • Exceptions up to level medium can be granted by any developer, but a comprehensive rationale has to be given why the risk is acceptable ("e.g. the affected functionality of the component is not enabled/not exposed because...")
  • Exceptions up to level high need approval from an additional developer
  • Exceptions for level Critical need approval from product owner

4. When to involve security

Always involve the security team when:

  • You modify authentication, authorization, cryptography, or secret handling.
  • You introduce a new external integration, plugin mechanism, or cross-instance feature.
  • You are uncertain about data classification or tenant isolation impacts.
  • You introduce temporary security debt that should be consciously accepted.

A short summary and a tag in the PR description is sufficient; the aim is early, focused feedback.

5. Further references

Following this guide ensures that individual changes remain aligned with the overall SSDLC and TR-03187 expectations without requiring you to work from the full text every time.